package it.uniroma2.art.owlart.langsearch;

import it.uniroma2.art.owlart.exceptions.ModelAccessException;
import it.uniroma2.art.owlart.langsearch.index.config.StandardAnalysisConfiguration;
import it.uniroma2.art.owlart.langsearch.search.OntIndexSearcher;
import it.uniroma2.art.owlart.model.ARTURIResource;
import it.uniroma2.art.owlart.models.impl.URIResourceIteratorFilteringResourceIterator;
import it.uniroma2.art.owlart.navigation.ARTURIResourceIterator;
import it.uniroma2.art.owlart.protegeimpl.models.OWLModelProtegeImpl;
import it.uniroma2.art.owlart.protegeimpl.start.AGROVOC_INFO;
import it.uniroma2.art.owlart.protegeimpl.start.FactoryBasedProtegeOWLARTLoader;
import it.uniroma2.art.owlart.protegeimpl.start.ProtegeOWLARTLoader;
import it.uniroma2.art.owlart.utilities.RDFIterators;

import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;

import org.apache.lucene.util.Version;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.Iterators;

/**
 * This class accesses MySQL-based AGROVOC ontology. It can be used to produce the CUSTOM indexes which are
 * created from instances of C_NOUN, according to the particular multilingual knowledge organization of first
 * OWL version of AGROVOC ontology<br/>
 * In addition to this, this class contains explicit Protege API code, which is used to manipulate results
 * which are returned by the OntologyIndexer in terms of OWL ART API.
 * 
 * 
 * @author Armando Stellato <stellato@info.uniroma2.it>
 * 
 */
public class AGROVOC_CONCURRENT_SEARCH_ProtegeDB_TestOld {

	protected static Logger logger = LoggerFactory.getLogger(AGROVOC_CONCURRENT_SEARCH_ProtegeDB_TestOld.class);

	public static void main(String[] args) {
		try {

			ProtegeOWLARTLoader loader =

			// this one is a very simple configuration with hard-coded parameters
			// new PreconfiguredDBProtegeOWLARTLoader(AGROVOC_INFO.current_agrovoc_small_DB);

			// the following one can be used to pass the config file of Protege as an argument to the program
			// use args instead of this string, which is here just to help locating the sample config file
			new FactoryBasedProtegeOWLARTLoader(AGROVOC_INFO.agrovocBaseNS, new File(
					"src/test/resources/agrovoc_protege-db_20110223_products.config"));

			OWLModelProtegeImpl model = loader.getOWLModel();

			String indexLocation = "./data/index";

			StandardAnalysisConfiguration conf = new StandardAnalysisConfiguration(Version.LUCENE_36, "en");
			conf.setLanguagesOfURILocalNames("en");
			OWLSearchEngine oi = new OWLSearchEngine(model, indexLocation, conf);

			String customIndexName = "c_nounInstances";

			// INDEX BUILDING (decomment this to redo indexing)
			// buildIndex(model, oi, customIndexName, indexLocation);

			// this needs to be built if an index is already present and the indexer is thus not initialized
			oi.createOntIndexSearcher();
			System.out.println("ontsearcher armed");

			Iterator<ARTURIResource> retrievedResources = null;

			// *************************************
			// example over AGROVOC ontology
			// *************************************

			oi.setTHRESHOLD(0.5);
			for (int i = 0; i < 10; i++) {
				new Thread(threadSearch("" + i, model, oi, customIndexName, retrievedResources)).start();
			}

		} catch (Exception e) {
			e.printStackTrace(System.err);
			logger.error(e.getMessage());

			System.err.flush();
			System.err.println("error");

			e.printStackTrace();
		}
	}

	public static Runnable threadSearch(final String thread, final OWLModelProtegeImpl model,
			final OWLSearchEngine oi, final String indexName,
			final Iterator<ARTURIResource> retrievedResources) {
		Runnable r = new Runnable() {
			public void run() {
				try {
					Collection<ARTURIResource> retrievedResources = oi.findResourcesForIndex(indexName,
							"nut", "en", OntIndexSearcher.EXACT_MATCH);
					getSearchResult(thread, model, retrievedResources);
				} catch (Exception iex) {
				}
			}
		};
		return r;
	}

	private static synchronized HashSet<String> getSearchResult(final String thread,
			OWLModelProtegeImpl model, Collection<ARTURIResource> retrievedResources) {
		HashSet<String> tempList = new HashSet<String>();
		ARTURIResource hasLexProp = model.createURIResource(AGROVOC_INFO.commonAIMBaseNS
				+ "hasLexicalization");
		for (ARTURIResource foundCNameURIResource : retrievedResources) {
			ARTURIResourceIterator associatedDomainObjects;
			try {
				associatedDomainObjects = RDFIterators.toURIResourceIterator(model.listSubjectsOfPredObjPair(
						hasLexProp, foundCNameURIResource, true));
				while (associatedDomainObjects.hasNext()) {
					ARTURIResource domainObject = associatedDomainObjects.next();
					// System.out.println("domainObject: " + domainObject);
					ARTURIResourceIterator associatedDomainClasses = RDFIterators.toURIResourceIterator(model
							.listTypes(domainObject, false));
					while (associatedDomainClasses.hasNext()) {
						ARTURIResource domainClass = associatedDomainClasses.next();
						// System.out.println("domainClass: " + domainClass);
						tempList.add(domainClass.getURI());
					}
					associatedDomainClasses.close();
				}
				associatedDomainObjects.close();
			} catch (ModelAccessException e) {
				e.printStackTrace();
			}
		}
		System.out.println("Results for thread: " + thread + " : "
				+ Iterators.toString(retrievedResources.iterator()));
		return tempList;
	}

	private static void buildIndex(OWLModelProtegeImpl model, OWLSearchEngine oi, String indexName,
			String indexLocation) throws ModelAccessException, IOException {
		System.out.println("building index at: " + indexLocation);
		ARTURIResource cnoun = model.createURIResource(AGROVOC_INFO.commonAIMBaseNS + "c_noun");
		ARTURIResourceIterator it = new URIResourceIteratorFilteringResourceIterator(model.listInstances(
				cnoun, false));
		oi.buildCustomIndex(indexName, it, true);
		logger.info("INDEX BUILT");
	}

}
